package com.africanmoviesmobile.ui;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;

import org.pixmob.httpclient.HttpClientException;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.africanmoviesmobile.R;
import com.africanmoviesmobile.util.bitmap.ImageCache.ImageCacheParams;
import com.africanmoviesmobile.util.bitmap.ImageFetcher;
import com.africanmoviesmobile.webservice.AmmWebService;
import com.africanmoviesmobile.webservice.BasicAsyncCallback;
import com.africanmoviesmobile.webservice.WebServiceException;
import com.africanmoviesmobile.webservice.inf.Playlist;
import com.africanmoviesmobile.webservice.inf.User;
import com.africanmoviesmobile.webservice.inf.WebserviceObject;

public class PlaylistActivity extends BaseActivity implements OnItemClickListener, OnScrollListener {
	
	private LayoutInflater mLayoutInflater;
	private ListView mPlaylistListView;
	private LinearLayout mLoadingProgress;
	private LinearLayout mEmptyPlaylist;
	
	private ImageFetcher mThumbnailImageFetcher;
	
	AmmWebService mAmmWebService;
	User mUser = null;
	
	private PlaylistAdapter mPlaylistAdapter;
	
	private boolean mLastItemVisible = false;
    private boolean mLoadingInProgress = false;
	private int mResultPage;
	private int mPageCount;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.playlist_activity);
		
		int thumbnailWidth = getResources().getDimensionPixelSize(R.dimen.thumbnail_width);
		int thumbnailHeight = getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
		mThumbnailImageFetcher = new ImageFetcher(this, thumbnailWidth, thumbnailHeight);
		mThumbnailImageFetcher.setLoadingImage(R.drawable.empty_photo);
		mThumbnailImageFetcher.addImageCache(getSupportFragmentManager(), new ImageCacheParams(this, CACHE_DIR_THUMBNAIL));
		
		mPlaylistAdapter = new PlaylistAdapter();
		
		mLayoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mLoadingProgress = (LinearLayout) mLayoutInflater.inflate(R.layout.loading_progress_small, null);
    	
		mEmptyPlaylist = (LinearLayout) findViewById(R.id.empty_playlist);
		
		mPlaylistListView = (ListView) findViewById(R.id.list);
		mPlaylistListView.setDividerHeight(0);
		mPlaylistListView.addHeaderView(mLoadingProgress);
		mPlaylistListView.setAdapter(mPlaylistAdapter);
		mPlaylistListView.setOnItemClickListener(this);
		mPlaylistListView.setOnScrollListener(this);
		
		registerForContextMenu(mPlaylistListView);
		
		mResultPage = 1;
		mAmmWebService = AmmWebService.getInstance(this);
		
		mAmmWebService.getUser(getLoginEmail(), new BasicAsyncCallback() {

			public void onComplete(final WebserviceObject[] result, final Object state) {

				User user = (User) result[0];
				
				if(user != null){
					
					mUser = user;
					
					Hashtable<String, String> params = new Hashtable<String, String>();
					params.put("page", Integer.toString(mResultPage));
					
					Playlist[] userPlaylist = null;
					
					try {
						userPlaylist = mUser.getPlaylist(params);
					} catch (HttpClientException e) {
						Log.w("AMM HttpClientException:", e.getMessage());
					} catch (IOException e) {
						Log.w("AMM IOException:", e.getMessage());
					} catch (WebServiceException e) {
						Log.w("AMM WebServiceException:", e.getMessage());
						toastMessage(e.getMessage());
					}
					
					if ((userPlaylist != null) && (userPlaylist.length > 0)) {
		
						mPageCount = mUser.getResultPageCount();
						
						runOnUiThread(new Runnable() {public void run() { mPlaylistListView.removeHeaderView(mLoadingProgress); }});
						
						for (int i = 0; i < userPlaylist.length; i++) {
							final Playlist playlist = (Playlist) userPlaylist[i];
							runOnUiThread(new Runnable() {public void run() { mPlaylistAdapter.add(playlist); }});	
						}
						
					}else{
						runOnUiThread(new Runnable() {
							public void run() {
								mPlaylistListView.removeHeaderView(mLoadingProgress);
								mEmptyPlaylist.setVisibility(View.VISIBLE);
							}
						});
					}	
				}
			}

			public void onHttpClientException(final HttpClientException e, final Object state) {
				Log.w("AMM HttpClientException:", e.getMessage());
			}
			
			public void onIOException(final IOException e, final Object state) {
				Log.w("AMM IOException:", e.getMessage());
			}

			public void onWebServiceException(final WebServiceException e, final Object state) {
				Log.w("AMM WebServiceException:", e.getMessage());
				toastMessage(R.string.user_info_error);
			}

		}, null);
		
	}
	
	@Override
    public void onResume() {
        super.onResume();
        mThumbnailImageFetcher.setExitTasksEarly(false);
        mPlaylistAdapter.notifyDataSetChanged();
    }

    @Override
    public void onPause() {
        super.onPause();
        mThumbnailImageFetcher.setPauseWork(false);
        mThumbnailImageFetcher.setExitTasksEarly(true);
        mThumbnailImageFetcher.flushCache();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mThumbnailImageFetcher.closeCache();
    }
	
    @Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    	final Intent intent = new Intent(this, MovieDetailActivity.class);
		intent.putExtra(MovieDetailActivity.EXTRA_MOVIE_ID, (int) id);
        startActivity(intent);
	}
    
    @Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		mLastItemVisible = (totalItemCount > 0) && (firstVisibleItem + visibleItemCount >= totalItemCount - 1);
	}
    
    @Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		/**
		 * Check that the scrolling has stopped, and that the last item is
		 * visible.
		 */
		if ((scrollState == OnScrollListener.SCROLL_STATE_IDLE) && mLastItemVisible) {

			//check if we still have more page left and we aren't loading any data
			if ((mResultPage < mPageCount) && (!mLoadingInProgress)) {
				mPlaylistListView.addFooterView(mLoadingProgress);
				mResultPage++;
				loadMorePlaylist();
				mLastItemVisible = false;
				mLoadingInProgress = true;
			}
			
		}
		
		// Pause fetcher to ensure smoother scrolling when flinging
        if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
            mThumbnailImageFetcher.setPauseWork(true);
        } else {
            mThumbnailImageFetcher.setPauseWork(false);
        }
	}
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(Menu.NONE, R.id.context_menu_preview, Menu.NONE, R.string.preview);
        menu.add(Menu.NONE, R.id.context_menu_play, Menu.NONE, R.string.play);
    }
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {
    	AdapterContextMenuInfo contextMenuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
	        case R.id.context_menu_preview:
	            playMovie((int) contextMenuInfo.id, R.string.preview);
	            return true;
	        case R.id.context_menu_play:
	            playMovie((int) contextMenuInfo.id, R.string.play);
	            return true;
	        }
        return super.onContextItemSelected(item);
    }
    
    private void loadMorePlaylist() {
    
    	Hashtable<String, String> params = new Hashtable<String, String>();
		params.put("page", Integer.toString(mResultPage));

		mUser.getPlaylist(params, new BasicAsyncCallback() {

		public void onComplete(final WebserviceObject[] result, final Object state) {

			runOnUiThread(new Runnable() {public void run() { mPlaylistListView.removeFooterView(mLoadingProgress); }});
			
			mLoadingInProgress = false;
			
			Playlist[] userPlaylist = (Playlist[]) result;

			if ((userPlaylist != null)) {
																	
				for (int i = 0; i < userPlaylist.length; i++) {
					
					final Playlist playlist = (Playlist) (userPlaylist[i]);
					
					runOnUiThread(new Runnable() {public void run() { mPlaylistAdapter.add(playlist); }});
					
				}
			} 
		}

		public void onHttpClientException(final HttpClientException e, final Object state) {
			mLoadingInProgress = false;
			runOnUiThread(new Runnable() {public void run() { mPlaylistListView.removeFooterView(mLoadingProgress); }});
			Log.w("AMM HttpClientException:", e.getMessage());
		}
		
		public void onIOException(final IOException e, final Object state) {
			mLoadingInProgress = false;
			runOnUiThread(new Runnable() {public void run() { mPlaylistListView.removeFooterView(mLoadingProgress); }});
			Log.w("AMM IOException:", e.getMessage());
		}

		public void onWebServiceException(final WebServiceException e, final Object state) {
			mLoadingInProgress = false;
			runOnUiThread(new Runnable() {public void run() { mPlaylistListView.removeFooterView(mLoadingProgress); }});
			Log.w("AMM WebServiceException:", e.getMessage());
			toastMessage(e.getMessage());
		}

	}, null);
    	
    }
    
	public class PlaylistAdapter extends BaseAdapter {

		private Vector<Playlist> mListElements = new Vector<Playlist>();
		
		private class ViewHolder {
			public TextView mMovieTitle;
			public TextView mMovieCast;
    	    public ImageView mMovieCover;
    	    public ImageView mMovieRating;
    	}
		
        public PlaylistAdapter() {
        }

        public int getCount() {
        	if (mListElements.isEmpty()) {
    			return 0;
    		} else {
    			return mListElements.size();
    		}
        }

        public Object getItem(int position) {
        	Playlist playlist = (Playlist) mListElements.elementAt(position);
        	return playlist;
        }

        public long getItemId(int position) {
        	Playlist playlist = (Playlist) mListElements.elementAt(position);
    		return playlist.getMovieId();
        }

        public View getView(int position, View convertView, ViewGroup parent) {

        	Playlist playlist = (Playlist) mListElements.elementAt(position);
        	
        	ViewHolder holder;
        	
        	View playlistRow = convertView;
        	
        	if(playlistRow == null){
        		playlistRow = mLayoutInflater.inflate(R.layout.movie_listview_row, parent, false);
            	
            	holder  = new ViewHolder();
        		holder.mMovieTitle = (TextView) playlistRow.findViewById(R.id.movie_title);
        		holder.mMovieCast = (TextView) playlistRow.findViewById(R.id.movie_cast);
        		holder.mMovieRating = (ImageView) playlistRow.findViewById(R.id.movie_rating);
        		holder.mMovieCover = (ImageView) playlistRow.findViewById(R.id.movie_cover);
        		
        		playlistRow.setTag(holder);
        	}else{
        		holder = (ViewHolder) playlistRow.getTag();
        	}
        	
        	holder.mMovieTitle.setText(playlist.getMovieTitle());
        	holder.mMovieCast.setText(playlist.getMovieShortCast());
        	holder.mMovieRating.setImageResource(mRatingsStarDarkArray[playlist.getMovieRatings()]);
        	mThumbnailImageFetcher.loadImage(playlist.getMovieCover(), holder.mMovieCover);
        	
        	return playlistRow;
        }
        
        public void add(Playlist data) {
        	mListElements.addElement(data);
            notifyDataSetChanged();
        }

    }
	
}
